package com.tokenplus.thai.anetwork

import com.tokenplus.thai.adata.coupons.ReqCouponUse
import com.tokenplus.thai.adata.coupons.ReqCouponVerify
import com.tokenplus.thai.data.*
import com.tokenplus.thai.adata.feedback.ReqFeedbackSubmit
import com.tokenplus.thai.adata.home.getInviteFriendEarn.ReqGetInviteFriendEarn
import com.tokenplus.thai.adata.income.ReqExtractInviteIncome
import com.tokenplus.thai.adata.income.ReqGetInviteIncomeData
import com.tokenplus.thai.adata.login.ReqChangePassword
import com.tokenplus.thai.adata.login.ReqLogin
import com.tokenplus.thai.adata.login.ReqRegister
import com.tokenplus.thai.adata.user.ReqGetMyTransactions
import com.tokenplus.thai.adata.user.ReqGetUserWallet
import com.tokenplus.thai.adata.user.ReqSetWalletName
import com.tokenplus.thai.adata.withdraw.ReqWithdrawCreate
import com.tokenplus.thai.extend.toFullUrlPath
import okhttp3.MultipartBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.http.Part
import retrofit2.http.QueryMap
import java.lang.RuntimeException
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

object ApiUserNetwork {

    private val garlic_loanServiceApi = ApiServiceCreator.create<ApiUserService>()

    suspend fun getIpInfo() =
        garlic_loanServiceApi.getIpInfo(
            ApiUrl.PathGetIpInfo
        ).await()

    suspend fun getInviteFriendEarn(reqGetInviteFriendEarn: ReqGetInviteFriendEarn) =
        garlic_loanServiceApi.getInviteFriendEarn(
            ApiUrl.PathGetInviteFriendEarn.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteFriendEarn
        ).await()

    suspend fun getInviteIncomeList(reqGetInviteFriendEarn: ReqGetInviteFriendEarn) =
        garlic_loanServiceApi.getInviteIncomeList(
            ApiUrl.PathGetInviteIncomeList.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteFriendEarn
        ).await()

    suspend fun getTransferInDetail(reqGetInviteFriendEarn: ReqGetInviteFriendEarn) =
        garlic_loanServiceApi.getTransferInDetail(
            ApiUrl.PathGetTransferInDetail.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteFriendEarn
        ).await()

    suspend fun getTransferInEarn(reqGetInviteFriendEarn: ReqGetInviteFriendEarn) =
        garlic_loanServiceApi.getTransferInEarn(
            ApiUrl.PathGetTransferInEarn.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteFriendEarn
        ).await()

    suspend fun getTransferInEarnList(reqGetInviteFriendEarn: ReqGetInviteFriendEarn) =
        garlic_loanServiceApi.getTransferInEarnList(
            ApiUrl.PathGetTransferInEarnList.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteFriendEarn
        ).await()

    suspend fun getTransferInExtractList(reqGetInviteFriendEarn: ReqGetInviteFriendEarn) =
        garlic_loanServiceApi.getTransferInExtractList(
            ApiUrl.PathGetTransferInExtractList.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteFriendEarn
        ).await()

    suspend fun appVersion(reqBase: ReqBase) =
        garlic_loanServiceApi.appVersion(
            ApiUrl.PathAppVersion.toFullUrlPath(),
            reqBase
        ).await()

    suspend fun getCoins(reqBase: ReqBase) =
        garlic_loanServiceApi.getCoins(
            ApiUrl.PathGetCoins.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun feedbackSubmit(reqFeedbackSubmit: ReqFeedbackSubmit) =
        garlic_loanServiceApi.feedbackSubmit(
            ApiUrl.PathFeedbackSubmit.toFullUrlPath(),
            ApiHeaderMap(),
            reqFeedbackSubmit
        ).await()

    suspend fun extractInviteIncome(reqExtractInviteIncome: ReqExtractInviteIncome) =
        garlic_loanServiceApi.extractInviteIncome(
            ApiUrl.PathExtractInviteIncome.toFullUrlPath(),
            ApiHeaderMap(),
            reqExtractInviteIncome
        ).await()

    suspend fun extractRechargeIncome(reqExtractInviteIncome: ReqExtractInviteIncome) =
        garlic_loanServiceApi.extractRechargeIncome(
            ApiUrl.PathExtractRechargeIncome.toFullUrlPath(),
            ApiHeaderMap(),
            reqExtractInviteIncome
        ).await()

    suspend fun getInviteIncomeData(reqGetInviteIncomeData: ReqGetInviteIncomeData) =
        garlic_loanServiceApi.getInviteIncomeData(
            ApiUrl.PathGetInviteIncomeData.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteIncomeData
        ).await()

    suspend fun getRechargeIncomeData(reqGetInviteIncomeData: ReqGetInviteIncomeData) =
        garlic_loanServiceApi.getRechargeIncomeData(
            ApiUrl.PathGetRechargeIncomeData.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetInviteIncomeData
        ).await()

    suspend fun detectUserInfo(reqLogin: ReqLogin) =
        garlic_loanServiceApi.detectUserInfo(
            ApiUrl.PathDetectUserInfo.toFullUrlPath(),
            ApiHeaderMap(),
            reqLogin
        ).await()

    suspend fun login(reqLogin: ReqLogin) =
        garlic_loanServiceApi.login(
            ApiUrl.PathLogin.toFullUrlPath(),
            ApiHeaderMap(),
            reqLogin
        ).await()

    suspend fun register(reqRegister: ReqRegister) =
        garlic_loanServiceApi.register(
            ApiUrl.PathRegister.toFullUrlPath(),
            ApiHeaderMap(),
            reqRegister
        ).await()

    suspend fun registerConfirm(reqRegister: ReqRegister) =
        garlic_loanServiceApi.registerConfirm(
            ApiUrl.PathRegisterConfirm.toFullUrlPath(),
            ApiHeaderMap(),
            reqRegister
        ).await()

    suspend fun changePassword(reqChangePassword: ReqChangePassword) =
        garlic_loanServiceApi.changePassword(
            ApiUrl.PathChangePassword.toFullUrlPath(),
            ApiHeaderMap(),
            reqChangePassword
        ).await()

    suspend fun getUserWallet(reqGetUserWallet: ReqGetUserWallet) =
        garlic_loanServiceApi.getUserWallet(
            ApiUrl.PathGetUserWallet.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetUserWallet
        ).await()

    suspend fun setWalletName(reqSetWalletName: ReqSetWalletName) =
        garlic_loanServiceApi.setWalletName(
            ApiUrl.PathSetWalletName.toFullUrlPath(),
            ApiHeaderMap(),
            reqSetWalletName
        ).await()

    suspend fun getUserAccounts(reqGetUserWallet: ReqGetUserWallet) =
        garlic_loanServiceApi.getUserAccounts(
            ApiUrl.PathGetUserAccounts.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetUserWallet
        ).await()

    suspend fun getMyInviteInfo(reqBase: ReqBase) =
        garlic_loanServiceApi.getMyInviteInfo(
            ApiUrl.PathGetMyInviteInfo.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun getMyTransactions(reqGetMyTransactions: ReqGetMyTransactions) =
        garlic_loanServiceApi.getMyTransactions(
            ApiUrl.PathGetMyTransactions.toFullUrlPath(),
            ApiHeaderMap(),
            reqGetMyTransactions
        ).await()

    suspend fun withdrawCreate(reqWithdrawCreate: ReqWithdrawCreate) =
        garlic_loanServiceApi.withdrawCreate(
            ApiUrl.PathWithdrawCreate.toFullUrlPath(),
            ApiHeaderMap(),
            reqWithdrawCreate
        ).await()

    suspend fun withdrawGetBalance(reqWithdrawCreate: ReqWithdrawCreate) =
        garlic_loanServiceApi.withdrawGetBalance(
            ApiUrl.PathWithdrawGetBalance.toFullUrlPath(),
            ApiHeaderMap(),
            reqWithdrawCreate
        ).await()

    suspend fun getRechargeIncomeConfig(reqBase: ReqBase) =
        garlic_loanServiceApi.getRechargeIncomeConfig(
            ApiUrl.PathGetRechargeIncomeConfig.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun uploadImage(
        @QueryMap map: Map<String, String>,
        @Part file: MultipartBody.Part,
    ) =
        garlic_loanServiceApi.uploadImage(
            ApiUrl.GARLICLOAN_PATH_UPLOAD_IMAGE.toFullUrlPath(),
            map,
            file
        ).await()

    suspend fun getCoupons(reqBase: ReqBase) =
        garlic_loanServiceApi.getCoupons(
            ApiUrl.PathGetCoupons.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun couponUse(reqCouponUse: ReqCouponUse) =
        garlic_loanServiceApi.couponUse(
            ApiUrl.PathCouponUse.toFullUrlPath(),
            ApiHeaderMap(),
            reqCouponUse
        ).await()

    suspend fun couponVerify(reqCouponVerify: ReqCouponVerify) =
        garlic_loanServiceApi.couponVerify(
            ApiUrl.PathCouponVerify.toFullUrlPath(),
            ApiHeaderMap(),
            reqCouponVerify
        ).await()

    suspend fun getNewComerEnjoy(reqBase: ReqBase) =
        garlic_loanServiceApi.getNewComerEnjoy(
            ApiUrl.PathGetNewComerEnjoy.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun getCheckinDetail(reqBase: ReqBase) =
        garlic_loanServiceApi.getCheckinDetail(
            ApiUrl.PathGetCheckinDetail.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun checkin(reqBase: ReqBase) =
        garlic_loanServiceApi.checkin(
            ApiUrl.PathGetCheckin.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun getRedMarkInfo(reqBase: ReqBase) =
        garlic_loanServiceApi.getRedMarkInfo(
            ApiUrl.PathGetRedMarkInfo.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    suspend fun getFirstRechargeConfig(reqBase: ReqBase) =
        garlic_loanServiceApi.getFirstRechargeConfig(
            ApiUrl.PathGetFirstRechargeConfig.toFullUrlPath(),
            ApiHeaderMap(),
            reqBase
        ).await()

    private suspend fun <T> Call<T>.await(): T {
        return suspendCoroutine { continuation ->
            enqueue(object : Callback<T> {
                override fun onResponse(call: Call<T>, response: Response<T>) {
                    val body = response.body()
                    if (body != null) continuation.resume(body)
                    else continuation.resumeWithException(
                        RuntimeException("response body is null")
                    )
                }

                override fun onFailure(call: Call<T>, t: Throwable) {
                    continuation.resumeWithException(t)
                }
            })
        }
    }
}